package com.ship.dispatch.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ship.common.business.service.impl.BaseServiceImpl;
import com.ship.dispatch.bean.HomePage.*;
import com.ship.dispatch.mapper.ConHomePageServerMapper;
import com.ship.dispatch.service.ConHomePageServer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;


@Service
public class ConHomePageServerImpl extends BaseServiceImpl<ConHomePageServerMapper, ConHomePage> implements ConHomePageServer {

    @Override
    @Transactional
    public void insetOrUpdateByImo(List<ConHomePage> conHomePageList) {
        this.baseMapper.deleteAll();
         if (!conHomePageList.isEmpty()) {
            this.saveBatch(conHomePageList);
        }
    }

    @Override
    public List<String> getAllImo() {
        return this.baseMapper.getAllImo();
    }

    @Override
    public List<ConHomePage> getAisStatus(List<String> imoList, String tableName) {
        return this.baseMapper.getAisStatus(imoList, tableName);
    }

    @Override
    public List<ConHomePage> getAll() {
        return this.baseMapper.getAll();
    }

    @Override
    public List<String> getAllConId() {
        return this.baseMapper.getAllConId();
    }

    @Override
    public List<ConHomePageAll> getByConIdList(List<String> conIdList) {
        return this.baseMapper.getByConIdList(conIdList);
    }

    @Override
    public List<Map<String, String>> getLastVoyage() {
        //获取sp_arrange_scheme_detail表中的信息
        List<ConHomePageArrage> infoByArrange = this.baseMapper.getInfoByArrange();

        if (infoByArrange != null && !infoByArrange.isEmpty()) {
            for (ConHomePageArrage arrage : infoByArrange) {
                if (arrage.getRealityUnloadingDate() == null) {
                    arrage.setRealityUnloadingDate(arrage.getExpectedUnloadingWindow());
                }
            }
        }
        List<String> imoList = infoByArrange.stream()
                .map(ConHomePageArrage::getImo)
                .collect(Collectors.toList());

//        System.out.println("imoList： "+imoList);

        //满足条件的off-hire
        List<ConHomePageArrageCon> conShippingOffHireList = this.baseMapper.getConInfoOffHireByImo(imoList);

        //满足条件的 redelivery_date_end
        List<ConHomePageArrageCon> conShippingLeaseList = this.baseMapper.getConInfoLeaseByImo(imoList);

        //取时间，并格式化
        List<Map<String, String>> infoByArrangeResult = extractFieldsToMap(infoByArrange, "imo", "realityUnloadingDate",1);
//        System.out.println("result: " + infoByArrangeResult);

        List<Map<String, String>> conShippingOffHireResult = extractFieldsToMap(conShippingOffHireList, "imo", "hireTimeValue",0);
//        System.out.println("result2: " + conShippingOffHireResult);

        List<Map<String, String>> conShippingLeaseResult = extractFieldsToMap(conShippingLeaseList, "imo", "redeliveryDateEnd",1);
//        System.out.println("result3: " + conShippingLeaseResult);

        // 合并结果，按 IMO 取最大值
        List<Map<String, String>> ImoResult = mergeResultsWithSource(infoByArrangeResult, conShippingLeaseResult, conShippingOffHireResult);

        //获取港口对应的国家
        List<PortCountry> portCountries = this.baseMapper.getPortInfo();

        //输出对应状态的上一航次信息
        List<Map<String,String>> finalResult = new ArrayList<>();

        // 遍历 finalResult，根据 source 进入不同处理逻辑
        for (Map<String, String> result : ImoResult) {
            String imo = result.get("imo");
//            String maxTimestamp = result.get("maxTimestamp");
            String source = result.get("source");

            if ("infoByArrangeResult".equals(source)) {
//                System.out.println("进入infoByArrangeResult的imo: "+imo);
                Map<String,String> handleInfoByArrange = handleInfoByArrange(imo, infoByArrange,portCountries);

                finalResult.add(handleInfoByArrange);
            } else if ("conShippingOffHireResult".equals(source)) {
//                System.out.println("进入conShippingOffHireResult的imo: "+imo);

                Map<String,String> handleConShippingOffHire = handleConShippingOffHire(imo, conShippingOffHireList);
                finalResult.add(handleConShippingOffHire);
            } else if ("conShippingLeaseResult".equals(source)) {
//                System.out.println("进入conShippingLeaseResult的imo: "+imo);

               Map<String,String> handleConShippingLease = handleConShippingLease(imo, conShippingLeaseList);
               finalResult.add(handleConShippingLease);
            }
        }

        return finalResult;
    }

    /**
     * 当前航次
     * @return
     */
    @Override
    public List<Map<String, String>> getNowVoyage(List<String> imolist) throws ParseException {

        List<Map<String, String>> result = new ArrayList<>();

        List<PortCountry> portCountries = this.baseMapper.getPortInfo();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");

        //场景1 船舶当前航次预计卸载时间最接近当前时间，并且当前时间大于预计卸载时间
        List<ConHomePageArrage> infoByArrangeOne = this.baseMapper.getGetNowVoyageByOne(imolist);
        if (infoByArrangeOne !=null ){
            for (ConHomePageArrage arrange : infoByArrangeOne) {
                Map<String, String> map = new HashMap<>();

                String realityLoadingDate = arrange.getRealityLoadingDate() != null ?
                        sdf.format(arrange.getRealityLoadingDate()) : sdf.format(arrange.getExpectedLoadingDate());
                String expectedUnloadingWindow = arrange.getExpectedUnloadingWindow() != null ?
                        sdf.format(arrange.getExpectedUnloadingWindow()) : "";

                // 查找港口对应的portCountry
                String expectedLoadingPort = arrange.getExpectedLoadingPort();
                String expectedUnloadingPort = arrange.getExpectedUnloadingPort();

                // 获取港口对应的国家
                String expectedLoadingPortCountry = getPortCountry(portCountries, expectedLoadingPort);
                String expectedUnloadingPortCountry = getPortCountry(portCountries, expectedUnloadingPort);

                String concatenatedValues = realityLoadingDate + " " + expectedLoadingPort + "," + expectedLoadingPortCountry
                        + " -> " + expectedUnloadingWindow + " " + expectedUnloadingPort + "," + expectedUnloadingPortCountry;

                map.put("shipName", arrange.getShipName());
                map.put("value", concatenatedValues);
//                System.out.println("进入场景1-----------" + arrange.getShipName());
                // 将map添加到结果列表中
                result.add(map);

                imolist.remove(arrange.getImo());
            }
        }
        if (!imolist.isEmpty()) {

            // 场景2 船舶当前航次预计卸载时间最接近当前时间，并且当前时间小于预计装载时间
            List<ConHomePageArrage> infoByArrangeTwoNow = this.baseMapper.getGetNowVoyageByTwoNow(imolist);

//            List<ConHomePageArrage> infoByArrangeTwoLast = this.baseMapper.getGetNowVoyageByTwoLast(imolist);
            List<ConHomePageArrage> infoByArrangeTwoLast = this.baseMapper.getInfoByArrange();


            if (infoByArrangeTwoLast != null && !infoByArrangeTwoLast.isEmpty()) {
                for (ConHomePageArrage arrage : infoByArrangeTwoLast) {
                    if (arrage.getRealityUnloadingDate() == null) {
                        arrage.setRealityUnloadingDate(arrage.getExpectedUnloadingWindow());
                    }
                }
            }

            //满足条件的off-hire
            List<ConHomePageArrageCon> conShippingOffHireList = this.baseMapper.getConInfoOffHireByImo(imolist);

            //满足条件的starting_date_of_lease_end
            List<ConHomePageArrageCon> conShippingLeaseList = this.baseMapper.getConInfoLeaseByImo(imolist);
//            List<ConHomePageArrageCon> conShippingLeaseList = this.baseMapper.getConInfoLeaseByImoNow(imolist);

            //取时间，并格式化
            List<Map<String, String>> infoByArrangeResult = extractFieldsToMap(infoByArrangeTwoLast, "imo", "realityUnloadingDate", 1);

            List<Map<String, String>> conShippingOffHireResult = extractFieldsToMap(conShippingOffHireList, "imo", "hireTimeValue", 0);

            List<Map<String, String>> conShippingLeaseResult = extractFieldsToMap(conShippingLeaseList, "imo", "redeliveryDateEnd", 1);

            // 合并结果，按 IMO 取最大值
            List<Map<String, String>> ImoResult = mergeResultsWithSource(infoByArrangeResult, conShippingLeaseResult, conShippingOffHireResult);

            // 查询所有off-hire
            List<ConHomePageArrageCon> conOffHireNow = this.baseMapper.getConOffHIreNow(imolist);

            // 创建一个 map 来缓存每个 imo 对应的 off-hire 时间段
            Map<String, Map<String, Object>> imoOffHireInfoMap = new HashMap<>();
            Date minStart = null; // off-hire 开始时间
            String offHireValue = ""; // off-hire 组合结果
            Date minDeliveryDateBegin = null; // 船舶租出时间（交船时间）
            String shipName = ""; // 船舶名称
            if (conOffHireNow != null && !conOffHireNow.isEmpty()) {
                // 预先遍历 conOffHireNow，缓存每个 imo 的相关信息
                for (ConHomePageArrageCon con : conOffHireNow) {
                    String imo = con.getImo();
                    shipName = con.getShipName();

                    String hireTimeValue = con.getHireTimeValue();
                    List<Map<String, String>> hireTimes = new ArrayList<>();
                    // 解析 hireTimeValue 为 JSON 数组
                    if (hireTimes != null && !hireTimes.isEmpty()) {
                        hireTimes = parseHireTimeValue(hireTimeValue);
                        // 筛选 start 大于当前时间的值，并找出最小值
                        Map<String, String> minStartRecord = hireTimes.stream()
                                .filter(time -> {
                                    Date startDate = parseToDate(time.get("start"));
                                    return startDate != null && isAfterNow(startDate);
                                }) // 筛选 start 大于当前时间的记录
                                .min(Comparator.comparing(time -> parseToDate(time.get("start")))) // 找到最小的 start 对应的记录
                                .orElse(null);

                        // 如果找到了最小的记录
                        if (minStartRecord != null) {
                            minStart = sdf.parse(minStartRecord.get("start").split(" ")[0].replace("-", "."));
                            String minStartStr = minStartRecord.get("start").split(" ")[0].replace("-", ".");
                            String minEnd = minStartRecord.get("end").split(" ")[0].replace("-", "."); // off-hire 结束时间
                            offHireValue = minStartStr + "-" + minEnd + " off-hire"; // 组合为 "start_end" 格式
                        }
                    }

                    // 记录船舶的交船日期大于当前时间
                    if (con.getDeliveryDateBegin() != null && con.getDeliveryDateBegin().after(new Date())) {
                        // 如果当前 imo 没有记录或者找到更小的交船日期，更新 minDeliveryDateBegin
                        if (minDeliveryDateBegin == null || con.getDeliveryDateBegin().before(minDeliveryDateBegin)) {
                            minDeliveryDateBegin = con.getDeliveryDateBegin();
                            shipName = con.getShipName(); // 更新船舶名称
                        }
                    } else {
                        minDeliveryDateBegin = null;
                    }

                    // 如果 imo 在 map 中已经存在，比较 minDeliveryDateBegin 更新最小值
                    if (!imoOffHireInfoMap.containsKey(imo)) {
                        // 将每个 imo 对应的数据存入缓存 map 中
                        Map<String, Object> imoOffHireInfo = new HashMap<>();
                        imoOffHireInfo.put("minStart", minStart);
                        imoOffHireInfo.put("offHireValue", offHireValue);
                        imoOffHireInfo.put("minDeliveryDateBegin", minDeliveryDateBegin);
                        imoOffHireInfo.put("shipName", shipName);

                        imoOffHireInfoMap.put(imo, imoOffHireInfo);
                    } else {
                        // 如果已有记录，比较并更新
                        Map<String, Object> existingInfo = imoOffHireInfoMap.get(imo);
                        Date existingDeliveryDate = (Date) existingInfo.get("minDeliveryDateBegin");

                        // 如果新的交船日期更早，更新记录
                        if (minDeliveryDateBegin != null && (existingDeliveryDate == null || minDeliveryDateBegin.before(existingDeliveryDate))) {
                            existingInfo.put("minStart", minStart);
                            existingInfo.put("offHireValue", offHireValue);
                            existingInfo.put("minDeliveryDateBegin", minDeliveryDateBegin);
                            existingInfo.put("shipName", shipName);
                        }
                    }
                }
            }

            // 遍历 finalResult，根据 source 进入不同处理逻辑
            for (Map<String, String> resultRealityUnloadingDate : ImoResult) {
                String imo = resultRealityUnloadingDate.get("imo");
                String source = resultRealityUnloadingDate.get("source");
                // 场景2 分支1 有上一航次
                if ("infoByArrangeResult".equals(source)) {
                    Map<String, String> handleInfoByArrange = handleInfoByArrangeTwo(imo, infoByArrangeTwoLast, portCountries, infoByArrangeTwoNow);
                    if (!handleInfoByArrange.isEmpty()) {
//                        System.out.println("进入场景2 分支1 有上一航次-------- add" + handleInfoByArrange);
                        result.add(handleInfoByArrange);
                    }
                    continue;
                }
                // 场景2 分支2 无上一航次

                if (conOffHireNow != null && !conOffHireNow.isEmpty()) {
                    Map<String, String> resultOfTwo = new HashMap<>();

                    if (imoOffHireInfoMap.containsKey(imo)) {
                        Map<String, Object> imoOffHireInfo = imoOffHireInfoMap.get(imo);
                        minStart = (Date) imoOffHireInfo.get("minStart");
                        offHireValue = (String) imoOffHireInfo.get("offHireValue");
                        minDeliveryDateBegin = (Date) imoOffHireInfo.get("minDeliveryDateBegin");
                        shipName = (String) imoOffHireInfo.get("shipName");
                    }

                    Date minExpectedLoadingDate = infoByArrangeTwoNow.stream()
                            .filter(arrange -> arrange.getImo().equals(imo)) // 筛选出当前 imo 的记录
                            .map(ConHomePageArrage::getExpectedLoadingDate) // 提取 ExpectedLoadingDate
                            .min(Date::compareTo) // 找到最小值
                            .orElse(null);
//                    if (minStart == null){
//                        System.out.println("预比较的minStart： " + minStart + "----------");
//                    }else {
//                        System.out.println("预比较的minStart： " + sdf.format(minStart) + "----------");
//                    }
//                    if (minExpectedLoadingDate == null){
//                        System.out.println("预比较的minExpectedLoadingDate： " + minExpectedLoadingDate + "----------");
//                    }else {
//                        System.out.println("预比较的minExpectedLoadingDate： " + sdf.format(minExpectedLoadingDate) + "----------");
//                    }
//                    if (minDeliveryDateBegin == null){
//                        System.out.println("预比较的minDeliveryDateBegin： " + minDeliveryDateBegin + "----------");
//                    }else {
//                        System.out.println("预比较的minDeliveryDateBegin： " + sdf.format(minDeliveryDateBegin) + "----------");
//                    }

                    // 比较三个时间，找出最小值
                    Date minDate = Stream.of(minStart, minExpectedLoadingDate, minDeliveryDateBegin)
                            .filter(Objects::nonNull) // 过滤非空值
                            .min(Date::compareTo) // 找出最小值
                            .orElse(null);

                    // 分别进入不同的逻辑分支
                    if (minDate != null && minDate.equals(minStart)) {
                        // 场景3 无上一航次 off-hire大于当前时间，小于预计装载时间和交船时间
                        resultOfTwo.put("shipName", shipName);
                        resultOfTwo.put("value", offHireValue);

//                        System.out.println("off-hire 最小 add" + shipName);
                        result.add(resultOfTwo);

                    }
                    if (minDate != null && minDate.equals(minExpectedLoadingDate)) {
                        // 场景2 分支2 无上一航次 且预计装载时间最小
                        Map<String, ConHomePageArrage> arrangeMap = infoByArrangeTwoNow.stream()
                                .collect(Collectors.toMap(ConHomePageArrage::getImo, arrange -> arrange));

                        ConHomePageArrage nowConHomePageArrage = arrangeMap.get(imo);

                        // 预计装载时间
                        Date expectedLoadingDate = nowConHomePageArrage.getExpectedLoadingDate();
                        String expectedLoadingDateStr = sdf.format(expectedLoadingDate);

                        // 装载港
                        String expectedLoadingPort = nowConHomePageArrage.getExpectedLoadingPort();
                        String expectedLoadingCountry = getPortCountry(portCountries, expectedLoadingPort);

                        // 预计卸载时间
                        Date expectedUnloadingWindow = nowConHomePageArrage.getExpectedUnloadingWindow();
                        String expectedUnloadingWindowStr = sdf.format(expectedUnloadingWindow);


                        // 卸载港
                        String expectedUnloadingPort = nowConHomePageArrage.getExpectedUnloadingPort();
                        String expectedUnloadingPortCountry = getPortCountry(portCountries, expectedUnloadingPort);

                        resultOfTwo.put("shipName", shipName);
                        resultOfTwo.put("value", expectedLoadingDateStr + " " + expectedLoadingPort + "," + expectedLoadingCountry + " -> " + expectedUnloadingWindowStr + " " + expectedUnloadingPort + "," + expectedUnloadingPortCountry);

//                        System.out.println("预计装载时间minExpectedLoadingDate 最小 add " + shipName);
                        result.add(resultOfTwo);

                    }
                    if (minDate != null && minDate.equals(minDeliveryDateBegin)) {

//                        Date deliveryDateBegin = conOffHireNow.stream()
//                                .filter(arrange -> arrange.getImo().equals(imo)) // 筛选出当前 imo 的记录
//                                .filter(arrange -> arrange.getDeliveryDateBegin() != null && arrange.getDeliveryDateBegin().after(new Date())) // 仅保留 deliveryDateBegin 大于当前时间的记录
//                                .map(ConHomePageArrageCon::getDeliveryDateBegin) // 提取 deliveryDateBegin
//                                .min(Date::compareTo) // 找到最小值
//                                .orElse(null);
//
//                        Date redeliveryDateEnd = conOffHireNow.stream()
//                                .filter(arrange -> arrange.getImo().equals(imo)) // 筛选出当前 imo 的记录
//                                .filter(arrange -> arrange.getRedeliveryDateEnd() != null && arrange.getRedeliveryDateEnd().after(new Date())) // 仅保留 redeliveryDateEnd 大于当前时间的记录
//                                .map(ConHomePageArrageCon::getRedeliveryDateEnd) // 提取 redeliveryDateEnd
//                                .min(Date::compareTo) // 找到最小值
//                                .orElse(null);
                        Optional<ConHomePageArrageCon> matchingArrange = conOffHireNow.stream()
                                .filter(arrange -> arrange.getImo().equals(imo)) // 筛选出当前 imo 的记录
                                .filter(arrange -> arrange.getDeliveryDateBegin() != null && arrange.getDeliveryDateBegin().after(new Date())) // deliveryDateBegin 大于当前时间
                                .filter(arrange -> arrange.getRedeliveryDateEnd() != null) // 确保 redeliveryDateEnd 不为 null
                                .min(Comparator.comparing(ConHomePageArrageCon::getDeliveryDateBegin)); // 按 deliveryDateBegin 找到最小值的记录

                        Date deliveryDateBegin = matchingArrange.map(ConHomePageArrageCon::getDeliveryDateBegin).orElse(null);
                        Date redeliveryDateEnd = matchingArrange.map(ConHomePageArrageCon::getRedeliveryDateEnd).orElse(null);
                        if (deliveryDateBegin != null && redeliveryDateEnd != null) {
                            String deliveryDateBeginStr = sdf.format(deliveryDateBegin); //租出合同交船时间
                            String redeliveryDateEndStr = sdf.format(redeliveryDateEnd); //租出合同还船时间

                            // 场景4 无上一航次 租出时间（交船时间）大于当前时间，小于预计装载时间和off-hire
                            resultOfTwo.put("shipName", shipName);
                            resultOfTwo.put("value", deliveryDateBeginStr + "-" + redeliveryDateEndStr + " 租出");
//                            System.out.println("交船时间 minDeliveryDateBegin最小 add" + shipName);

                            result.add(resultOfTwo);
                        }
                    }
                }
            }
        }

        return result;
    }

    private Map<String, String> handleInfoByArrangeTwo(String imo, List<ConHomePageArrage> infoByArrangeTwoLast, List<PortCountry> portCountries ,List<ConHomePageArrage> infoByArrangeTwoNow) {

        Map<String, String> result = new HashMap<>();

        Map<String, ConHomePageArrage> infoByArrangeMap = infoByArrangeTwoLast.stream()
                .collect(Collectors.toMap(ConHomePageArrage::getImo, Function.identity()));

        Map<String, ConHomePageArrage> infoByArrangeNowMap = infoByArrangeTwoNow.stream()
                .collect(Collectors.toMap(ConHomePageArrage::getImo, Function.identity()));

        Map<String, String> portCountryMap = portCountries.stream()
                .collect(Collectors.toMap(PortCountry::getPortNameEnglish, PortCountry::getPortCountry));

        ConHomePageArrage conHomePageArrageLast = infoByArrangeMap.get(imo);

        ConHomePageArrage conHomePageArrageNow = infoByArrangeNowMap.get(imo);

        if ( conHomePageArrageLast != null && conHomePageArrageNow != null) {
            String expectedLoadingCountry = portCountryMap.getOrDefault(conHomePageArrageNow.getExpectedLoadingPort(), "Unknown");

            String loadingPort = conHomePageArrageLast.getRealityLoadingPort();

            if (loadingPort == null ){
                loadingPort = conHomePageArrageLast.getExpectedUnloadingPort();
            }
            String expectedUnloadingCountry = portCountryMap.getOrDefault(loadingPort, "Unknown");

            String value = "";

            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");

                // 检查 realityUnloadingDate 是否为空
                String realityUnloadingDateFormatted = conHomePageArrageLast.getRealityUnloadingDate() != null
                        ? sdf.format(conHomePageArrageLast.getRealityUnloadingDate())
                        : sdf.format(conHomePageArrageLast.getExpectedLoadingDate());

                // 检查 realityLoadingDate 是否为空
                String expectedLoadingDateFormatted = conHomePageArrageNow.getExpectedLoadingDate() != null
                        ? sdf.format(conHomePageArrageNow.getExpectedLoadingDate())
                        : "";

                value = realityUnloadingDateFormatted + " " +
                        loadingPort + "," +
                        expectedUnloadingCountry + " -> " +
                        expectedLoadingDateFormatted + " " +
                        conHomePageArrageNow.getExpectedLoadingPort() + "," +
                        expectedLoadingCountry;
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 将 IMO 和拼接的值存入 Map
            result.put("shipName", conHomePageArrageNow.getShipName());
            result.put("value", value);
        }
        return result;
    }

    private String getPortCountry(List<PortCountry> portCountries, String portName) {
        for (PortCountry portCountry : portCountries) {
            if (portCountry.getPortNameEnglish().equalsIgnoreCase(portName)) {
                return portCountry.getPortCountry();
            }
        }
        return "";
    }

    private Map<String, String> handleInfoByArrange(String imo, List<ConHomePageArrage> infoByArrange, List<PortCountry> portCountries) {
        Map<String, String> result = new HashMap<>();

        Map<String, ConHomePageArrage> infoByArrangeMap = infoByArrange.stream()
                .collect(Collectors.toMap(ConHomePageArrage::getImo, Function.identity()));

        Map<String, String> portCountryMap = portCountries.stream()
                .collect(Collectors.toMap(PortCountry::getPortNameEnglish, PortCountry::getPortCountry));

        ConHomePageArrage conHomePageArrage = infoByArrangeMap.get(imo);

        if (conHomePageArrage != null) {

            String expectedLoadingCountry = portCountryMap.getOrDefault(conHomePageArrage.getExpectedLoadingPort(), "Unknown");

            String loadingPort = conHomePageArrage.getRealityLoadingPort();

            if (loadingPort == null ){
                loadingPort = conHomePageArrage.getExpectedUnloadingPort();
            }

            String expectedUnloadingCountry = portCountryMap.getOrDefault(loadingPort, "Unknown");

            String value = "";

            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");

                // 检查 realityLoadingDate 是否为空
                String realityLoadingDateFormatted = conHomePageArrage.getRealityLoadingDate() != null
                        ? sdf.format(conHomePageArrage.getRealityLoadingDate())
                        : sdf.format(conHomePageArrage.getExpectedLoadingDate());

                // 检查 realityUnloadingDate 是否为空
                String realityUnloadingDateFormatted = conHomePageArrage.getRealityUnloadingDate() != null
                        ? sdf.format(conHomePageArrage.getRealityUnloadingDate())
                        : sdf.format(conHomePageArrage.getExpectedUnloadingWindow());

                value = realityLoadingDateFormatted + " " +
                        conHomePageArrage.getExpectedLoadingPort() + "," +
                        expectedLoadingCountry + " -> " +
                        realityUnloadingDateFormatted + " " +
                        loadingPort + "," +
                        expectedUnloadingCountry;
            } catch (Exception e) {
                e.printStackTrace();
            }

            // 将 IMO 和拼接的值存入 Map
            result.put("shipName", conHomePageArrage.getShipName());
            result.put("value", value);
        }

        return result;
    }

    private Map<String, String> handleConShippingOffHire(String imo, List<ConHomePageArrageCon> conShippingOffHireList) {
        Map<String, String> result = new HashMap<>();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        ObjectMapper objectMapper = new ObjectMapper(); // 用于解析JSON

        // 获取当前时间
        Date currentTime = new Date();

        // 遍历conShippingOffHireList
        for (ConHomePageArrageCon item : conShippingOffHireList) {
            if (item.getImo().equals(imo)) { // 找到匹配的IMO
                String shipName = item.getShipName();
                String hireTimeValue = item.getHireTimeValue();

                try {
                    // 解析JSON字符串为时间段列表
                    List<Map<String, String>> hireTimeList = objectMapper.readValue(hireTimeValue, List.class);

                    // 存储符合条件的时间段
                    Map<String, String> matchedTime = null;

                    // 遍历hireTimeValue中的每一项
                    for (Map<String, String> timePeriod : hireTimeList) {
                        Date start = sdf.parse(timePeriod.get("start"));
                        Date end = sdf.parse(timePeriod.get("end"));

                        // 判断start和end是否都小于当前时间
                        if (start.before(currentTime) && end.before(currentTime)) {
                            // 找到符合条件的时间段
                            if (matchedTime == null || end.after(sdf.parse(matchedTime.get("end")))) {
                                matchedTime = timePeriod;
                            }
                        }
                    }

                    // 如果找到符合条件的时间段，则拼接结果
                    if (matchedTime != null) {
                        String start = matchedTime.get("start").split(" ")[0].replace("-", ".");
                        String end = matchedTime.get("end").split(" ")[0].replace("-", ".");
                        result.put("shipName", shipName);
                        result.put("value", start + "-" + end + " off-hire");
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    private Map<String, String> handleConShippingLease(String imo, List<ConHomePageArrageCon> conShippingLeaseList) {
        Map<String, String> result = new HashMap<>();

        Date currentTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");


        // 遍历conShippingLeaseList
        for (ConHomePageArrageCon item : conShippingLeaseList) {
            if (item.getImo().equals(imo)) {
                String shipName = item.getShipName();
                Date deliveryDateBegin = item.getDeliveryDateBegin();
                Date redeliveryDateEnd = item.getRedeliveryDateEnd();

                if (deliveryDateBegin.before(currentTime)) {
                    String formattedDeliveryDateBegin = sdf.format(deliveryDateBegin);
                    String formattedRedeliveryDateEnd = sdf.format(redeliveryDateEnd);
                    // 返回结果：拼接redeliveryDateEnd和deliveryDateEnd
                    result.put("shipName", shipName);
                    result.put("value", formattedDeliveryDateBegin + "-" + formattedRedeliveryDateEnd + " 租出");
                }
            }
        }
        return result;
    }

    public static <T> List<Map<String, String>> extractFieldsToMap(List<T> inputList, String field1, String field2, int formatOption) {
        List<Map<String, String>> resultList = new ArrayList<>();
        if (inputList == null || inputList.isEmpty() || field1 == null || field2 == null) {
            return resultList;
        }

        for (T item : inputList) {
            try {
                Map<String, String> map = new HashMap<>();
                Field field1Value = item.getClass().getDeclaredField(field1);
                Field field2Value = item.getClass().getDeclaredField(field2);
                field1Value.setAccessible(true);
                field2Value.setAccessible(true);

                // 获取字段值
                String value1 = String.valueOf(field1Value.get(item));
                Object field2RawValue = field2Value.get(item);

                // 根据 formatOption 格式化第二个字段
                String value2;
                if (formatOption == 1) {
                    // 转换为时间戳（假定字段是日期类型）
                    if (field2RawValue instanceof Date) {
                        value2 = String.valueOf(((Date) field2RawValue).getTime());
                    } else if (field2RawValue instanceof String) {
                        // 假定日期字符串格式为 "yyyy-MM-dd HH:mm:ss"
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date parsedDate = sdf.parse(field2RawValue.toString());
                        value2 = String.valueOf(parsedDate.getTime());
                    } else {
                        value2 = "Invalid Date";
                    }
                } else {
                    // 从 JSON 格式字符串中提取最大的 "end"
                    if (field2RawValue instanceof String && ((String) field2RawValue).startsWith("[")) {
                        String maxEnd = getMaxEndFromJson((String) field2RawValue);
                        if (maxEnd != null && !"0".equals(maxEnd) && isBeforeNow(maxEnd)) { // 添加条件，确保小于当前时间，空的跳过
                            value2 = maxEnd;
                        } else {
                            value2 = null; // 如果条件不满足，可以选择赋值为 null 或其他默认值
                        }
                    } else {
                        value2 = String.valueOf(field2RawValue);
                    }
                }
                map.put(value1,value2);
                resultList.add(map);

            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException("取字段发生错误： " + field1 + " 或 " + field2, e);
            } catch (Exception e) {
                throw new RuntimeException("格式化字段发生错误： " + field2, e);
            }
        }
        return resultList;
    }

    private static String getMaxEndFromJson(String jsonString) {
        // 使用正则表达式提取 "end" 值
        Pattern pattern = Pattern.compile("\"end\":\"(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2})\"");
        Matcher matcher = pattern.matcher(jsonString);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date maxDate = null;

        while (matcher.find()) {
            String endValue = matcher.group(1); // 获取 "end" 的值
            try {
                Date parsedDate = sdf.parse(endValue);
                if (maxDate == null || parsedDate.after(maxDate)) {
                    maxDate = parsedDate;
                }
            } catch (Exception e) {
                // 忽略无效日期
            }
        }

        return maxDate != null ? String.valueOf(maxDate.getTime()) : "0";
    }

    // 工具方法：解析 hireTimeValue 为 JSON 数组
    private List<Map<String, String>> parseHireTimeValue(String hireTimeValue) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(hireTimeValue, new TypeReference<List<Map<String, String>>>() {});
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private boolean isAfterNow(Date date) {
        return date != null && date.after(new Date());
    }

    private static boolean isBeforeNow(String dateTimeStr) {
        try {
            // 根据实际的时间格式解析，例如 "yyyy-MM-dd HH:mm:ss"
            long epochMillis = Long.parseLong(dateTimeStr);
            LocalDateTime dateTime = Instant.ofEpochMilli(epochMillis)
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
            return dateTime.isBefore(LocalDateTime.now());
        } catch (DateTimeParseException e) {
            e.printStackTrace();
            return false; // 如果解析失败，可以选择返回 false
        }
    }

    private Date parseToDate(String dateTime) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            return dateFormat.parse(dateTime);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private List<Map<String, String>> mergeResultsWithSource(List<Map<String, String>> list1, List<Map<String, String>> list2, List<Map<String, String>> list3) {
        // 创建一个 Map，以 IMO 为 key，存储最大时间戳和来源
        Map<String, ResultWithSource> imoMaxTimestampMap = new HashMap<>();

        // 更新 IMO 的最大时间戳和来源
        updateMaxTimestampWithSource(imoMaxTimestampMap, list1, "infoByArrangeResult");
        updateMaxTimestampWithSource(imoMaxTimestampMap, list2, "conShippingLeaseResult");
        updateMaxTimestampWithSource(imoMaxTimestampMap, list3, "conShippingOffHireResult");

        // 将结果转换回 List<Map<String, String>>
        List<Map<String, String>> result = new ArrayList<>();
        for (Map.Entry<String, ResultWithSource> entry : imoMaxTimestampMap.entrySet()) {
            Map<String, String> map = new HashMap<>();
            map.put("imo", entry.getKey());
            map.put("maxTimestamp", String.valueOf(entry.getValue().getMaxTimestamp()));
            map.put("source", entry.getValue().getSource());
            result.add(map);
        }

        return result;
    }

    private void updateMaxTimestampWithSource(Map<String, ResultWithSource> imoMaxTimestampMap, List<Map<String, String>> sourceList, String source) {
        for (Map<String, String> map : sourceList) {
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String imo = entry.getKey();
                String timestampStr = entry.getValue();
                try {
                    Long timestamp = Long.parseLong(timestampStr);
                    // 更新最大值和来源
                    imoMaxTimestampMap.compute(imo, (key, existing) -> {
                        if (existing == null || timestamp > existing.getMaxTimestamp()) {
                            return new ResultWithSource(timestamp, source);
                        }
                        return existing;
                    });
                } catch (NumberFormatException e) {
                    // 忽略无效的时间戳
//                    System.err.println("无效的时间戳: " + timestampStr);
                }
            }
        }
    }
}
